package controllers;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;

import javax.swing.JOptionPane;

import model.SearchPhotoModel;
import view.AddPhotoToDBGUI;
import client.CliMessage;
import client.ImageSerializer;

/**
 * The Class AddPhotoToDBController.
 * @author Tomer
 */
public class AddPhotoToDBController extends AbstractController
{

	/** The add photo view. */
	private AddPhotoToDBGUI addPhotoView;
	
	/** The add photo model. */
	private SearchPhotoModel addPhotoModel;
	
	/** The file path. */
	private String filePath;
	
	/** The file name. */
	public String fileName;

	/**
	 * Instantiates a new adds the photo to db controller.
	 *
	 * @param addPhotoView the add photo view
	 * @param addPhotoModel the add photo model
	 */
	public AddPhotoToDBController(AddPhotoToDBGUI addPhotoView, SearchPhotoModel addPhotoModel) 
	{
		super(addPhotoView, addPhotoModel);
		this.addPhotoModel = addPhotoModel;
		this.addPhotoView = addPhotoView;
		addPhotoView.addSearchActionListener(new AddButtonListener());
	}

	/* (non-Javadoc)
	 * @see client.IObserve#handleDBRequestSuccess()
	 */
	@Override
	public void handleDBRequestSuccess() 
	{
		//photo was added!
		addPhotoView.displayInfoMessage("Photo was added successfully.", "photo added", 1);
	}

	/* (non-Javadoc)
	 * @see client.IObserve#handleNullSearchResult()
	 */
	@Override
	public void handleNullSearchResult() 
	{
		int location = addPhotoModel.getLocation();
		String timeStamp = addPhotoModel.getTimeStamp();
		
		//serialize the photo
		ImageSerializer photoSerializer = new ImageSerializer(filePath);
		String serializedPhoto = photoSerializer.serializePhoto();
		
		//no such photo - send a query to create a new photo tuple in DB and send file to server
		String addPhotoQueryAndData = "addphoto"+"c:/sgip/newsrc/"+fileName	+"INSERT INTO photos "
																			+"(location,timestamp,LinkTofile) VALUES "
																			+"(" + location + ",'" + timeStamp + "'," + "'c:/sgip/newsrc/"+fileName+ "')";
		sendToServer(addPhotoQueryAndData+"<"+serializedPhoto);			
	}

	/* (non-Javadoc)
	 * @see client.IObserve#handleDBSearchResult(client.CliMessage)
	 */
	@Override
	public void handleDBSearchResult(CliMessage dbResult) 
	{
		// the photo already exists - ask the user if he is wants to replace it.
		int result = JOptionPane.showConfirmDialog(addPhotoView,"There is a photo with the same details in the data base.\n"+
													"Would you like you want to replace the link to file?"
													,"Confirm photo Replace"
													,JOptionPane.YES_NO_OPTION,
													JOptionPane.WARNING_MESSAGE);
		if(result == JOptionPane.NO_OPTION)
			return;
		
		//the user clicked "YES" - replace the photo
		int location = addPhotoModel.getLocation();
		String timeStamp = addPhotoModel.getTimeStamp();
		
		//serialize the photo
		ImageSerializer photoSerializer = new ImageSerializer(filePath);
		String serializedPhoto = photoSerializer.serializePhoto();
		
		String addPhotoQueryAndData = "addphoto"+"c:/sgip/newsrc/"+fileName+"UPDATE photos "
																	+"SET LinkToFile = 'c:/sgip/newsrc/"+fileName+"' "
																	+"WHERE Location = "+location+" "
																	+"AND TimeStamp ='"+timeStamp+"' ";	
		sendToServer(addPhotoQueryAndData+"<"+serializedPhoto);
	}
	
	/**
	 * The listener interface for receiving addButton events.
	 * The class that is interested in processing a addButton
	 * event implements this interface, and the object created
	 * with that class is registered with a component using the
	 * component's <code>addAddButtonListener<code> method. When
	 * the addButton event occurs, that object's appropriate
	 * method is invoked.
	 *
	 * @see AddButtonEvent
	 */
	class AddButtonListener implements ActionListener , IValidateInput
	{
		
		/* (non-Javadoc)
		 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
		 */
		@Override
		public void actionPerformed(ActionEvent e) 
		{
			//validate the input
			if(!validateInput())
				return;
			
			//save retrieved data
			int location = Integer.parseInt(addPhotoView.getLocationString());
			String timeStamp = addPhotoView.getTimestamp();
			addPhotoModel.setLocation(location);
			addPhotoModel.setTimeStamp(timeStamp);
			filePath = addPhotoView.getLinkToFile();
			
			//validate filepath
			fileName = extractFilenameFromFilepath(filePath);
			if (fileName == null)
			{
				addPhotoView.displayInfoMessage("The file path you typed is invalid!", "Can not open file", 2);
				System.out.println("can't open file: "+filePath);
				return;
			}
			
			
			//search the photo in DB
			String searchQuary = "search"	+"SELECT * "
											+"FROM photos AS p "
											+"WHERE p.Location = "+location+" "
											+"AND p.TimeStamp = '"+timeStamp+"'";

			sendToServer(searchQuary);
		
		}
		
		/* (non-Javadoc)
		 * @see controllers.IValidateInput#validateInput()
		 */
		@Override
		public boolean validateInput() 
		{
			try
			{
				//if there is no location entered or the location is not an integer - an exception is thrown
				if(addPhotoView.getLocationString() == null)
					throw new IOException();
				Integer.parseInt(addPhotoView.getLocationString());
				return true;
			}
			catch(Exception e)
			{
				//catch an exception thrown and inform user
				addPhotoView.displayInfoMessage("Error: location must consist of digits only!",
												"Invalid input", 0);
				e.printStackTrace();
				return false;
			}
		}
		
	}

	
	/**
	 * Extract filename from filepath.
	 *
	 * @param filepath the filepath
	 * @return the string
	 */
	private String extractFilenameFromFilepath(String filepath)
	{
		File f = new File(filepath);
		if((!f.canRead()) || (!f.exists()) || (f.isDirectory()) || (f.isHidden()) || (!f.canWrite()) )
			
			return null;
		System.out.println(f.getName());
		return f.getName();
	}

}
